/* 封装 axios 用于发送请求 */
import axios from 'axios'
import { ElMessage, ElLoading } from 'element-plus'
import type { LoadingInstance } from 'element-plus'
import { getActivePinia } from 'pinia'
import { useCounterStore } from '@/stores/modules/user'

import router from '../router'
const baseURL = 'http://big-event-vue-api-t.itheima.net'
// ② 不要再顶层调用 useXxx()
let loadingInstance: LoadingInstance

const request = axios.create({
  baseURL: baseURL,
  timeout: 10000,
})

request.interceptors.request.use(
  (config) => {
    if (getActivePinia()) {
      const store = useCounterStore()
      const token = store.getToken()
      if (token) config.headers.Authorization = token
    }

    loadingInstance = ElLoading.service({
      lock: true,
      text: '加载中…',
      background: 'rgba(0,0,0,0.7)',
    })
    return config
  },
  (error) => {
    loadingInstance?.close()
    ElMessage.error(error.message)
    return Promise.reject(error)
  },
)

request.interceptors.response.use(
  (response) => {
    loadingInstance?.close()

    const { data } = response
    if (data.code === 0) {
      return data
    }

    ElMessage.error(data.message || '业务错误')
    return Promise.reject(data.message)
  },
  (error) => {
    loadingInstance?.close()
    if (error.status === 401) {
      const route = router.currentRoute.value
      if (route.path !== '/login') {
        ElMessage.error('登录超时')
        router.replace({ path: '/login', query: { redirect: route.fullPath } })
      }
      return
    }
    ElMessage.error(error.message || '网络错误')
    return Promise.reject(error)
  },
)

/* 导出业务方法 */
export const get = (url: string, params?: object) => request.get(url, { params })

export const postForm = (url: string, data?: object) =>
  request.post(url, data, {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  })

export const postFormData = (url: string, params?: object) => {
  const fd = new FormData()
  const data = params as Record<string, any>
  Object.keys(data).forEach((k) => fd.append(k, data[k]))
  return request.post(url, fd)
}

export const postJSON = (url: string, data?: object) =>
  request.post(url, data, {
    headers: { 'Content-Type': 'application/json;charset=UTF-8' },
  })
export const deletedJson = (url: string, data?: object) => {
  request.delete(url, { data })
}
export const deleted = (url: string, params?: object) => {
  return request.delete(url, {
    params,
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  })
}

export const putJSON = (url: string, data?: object) =>
  request.put(url, data, {
    headers: { 'Content-Type': 'application/json;charset=UTF-8' },
  })

export const putForm = (url: string, data?: object) =>
  request.put(url, data, {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  })

export const putFormData = (url: string, params?: object) => {
  const fd = new FormData()
  const data = params as Record<string, any>
  Object.keys(data).forEach((k) => fd.append(k, data[k]))
  return request.put(url, fd)
}

export const patchJSON = (url: string, data?: object) =>
  request.patch(url, data, {
    headers: { 'Content-Type': 'application/json;charset=UTF-8' },
  })
export default request
export { baseURL }
